package com.gxc.array;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 682. 棒球比赛
 * 你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成，过去几回合的得分可能会影响以后几回合的得分。
 *
 * 比赛开始时，记录是空白的。你会得到一个记录操作的字符串列表 ops，其中 ops[i] 是你需要记录的第 i 项操作，ops 遵循下述规则：
 *
 * 整数 x - 表示本回合新获得分数 x
 * "+" - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
 * "D" - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
 * "C" - 表示前一次得分无效，将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。
 * 请你返回记录中所有得分的总和。
 */
public class CalPoints {

    public static void main(String[] args) {
        System.out.println(handle(new String[]{"5","2","C","D","+"}));
    }

    /**
     * 不能用几个变量解决（C可能连续）
     * 需要额外空间
     * @param operations
     * @return
     */
    public static int handle(String[] operations) {
        Stack<Integer> stack = new Stack<>();
        int res = 0;
        int prev = 0;
        int cur = 0;

        for (int i = 0; i < operations.length; i++) {
            if ("+".equals(operations[i])) {
                prev = stack.pop();
                cur = prev + stack.peek();
                res =  res + cur;
                stack.push(prev);
                stack.push(cur);
            } else if ("D".equals(operations[i])) {
                cur = 2 * stack.peek();
                res = res + cur;
                stack.push(cur);
            } else if ("C".equals(operations[i])) {
                res = res - stack.pop();
            } else {
                cur = Integer.valueOf(operations[i]);
                res = res + cur;
                stack.push(cur);
            }
        }
        return res;
    }

    /**
     * 可变长数组==链表
     */
    class Solution {
        public int calPoints(String[] ops) {
            int ret = 0;
            List<Integer> points = new ArrayList<Integer>();
            for (String op : ops) {
                int n = points.size();
                switch (op.charAt(0)) {
                    case '+':
                        ret += points.get(n - 1) + points.get(n - 2);
                        points.add(points.get(n - 1) + points.get(n - 2));
                        break;
                    case 'D':
                        ret += 2 * points.get(n - 1);
                        points.add(2 * points.get(n - 1));
                        break;
                    case 'C':
                        ret -= points.get(n - 1);
                        points.remove(n - 1);
                        break;
                    default:
                        ret += Integer.parseInt(op);
                        points.add(Integer.parseInt(op));
                        break;
                }
            }
            return ret;
        }
    }

}
